// svg-icon.vue
<script setup lang="ts">
import { Base64 } from './base64';

const props = withDefaults(
  defineProps<{
    src: string
    color?: string
    width?: string
    height?: string
    fillIndex?: number
  }>(),
  {
    color: '',
    width: '60px',
    height: '60px',
    fillIndex: 3,
  },
);

defineEmits(['click']);

const base64 = new Base64();

const svgData = ref('')

const changeColor = (sourceFile: string, color: string) => {
  let newSvg;
  if (/fill=".*?"/.test(sourceFile)) {
    newSvg = sourceFile.replace(/fill=".*?"/g, `fill="${color}"`);
  }
  else {
    newSvg = sourceFile.replace(/<svg /g, `<svg fill="${color}" `);
  }
  return newSvg;
};

const getAppFileManager = (url: string) => {
  // #ifdef APP-PLUS
  return new Promise((resolve, reject) => {
    plus.io.resolveLocalFileSystemURL(
      url,
      (entry) => {
        (
          entry as PlusIoDirectoryEntry & {
            file: (
              success: (file: PlusIoFile) => void,
              fail: (err: any) => void,
            ) => void
          }
        ).file(
          (file: PlusIoFile) => resolve(file),
          err => reject(err),
        );
      },
      err => reject(err),
    );
  })
  // #endif
};

const fetchSvgFile = async (src: string, color: string) => {
  try {
    let sourceFile: string;

    // 判断是否为本地文件路径
    if (src.startsWith('/static/') || src.startsWith('./static/')) {
      // 在微信小程序中，需要获取小程序包内的文件路径
      const filePath = src.startsWith('./') ? src.slice(2) : src.slice(1);

      // #ifdef MP-WEIXIN
      // 本地文件，使用文件系统管理器读取
      const fileManager = uni.getFileSystemManager();

      sourceFile = await new Promise((resolve, reject) => {
        fileManager.readFile({
          filePath,
          encoding: 'utf8',
          success: (res) => {
            resolve(res.data as string);
          },
          fail: (err) => {
            // console.error('读取本地文件失败:', err)
            reject(err);
          },
        });
      })
      // #endif

      // #ifdef APP-PLUS
      // App 端使用 plus.io 读取文件
      const file = await getAppFileManager(filePath);
      sourceFile = await new Promise((resolve, reject) => {
        const fileReader = new plus.io.FileReader();
        fileReader.readAsText(file as PlusIoFile, 'utf-8')
        fileReader.onloadend = (e) => {
          resolve(
            (e.target as PlusIoDirectoryEntry & { result: string })
              ?.result as string,
          );
        };
        fileReader.onerror = (e) => {
          reject(e);
        };
      });
      // #endif
    }
    else {
      // 远程文件，使用网络请求
      const response = await uni.request({
        url: src,
        method: 'GET',
      });

      // 在微信小程序中，response.data 直接包含响应内容
      sourceFile = response.data as string;
    }

    const newFile = changeColor(sourceFile, color);
    const svgBase64File = base64.encode(newFile);
    svgData.value = `data:image/svg+xml;base64,${svgBase64File}`;
  }
  catch (_error) {
    console.error('获取SVG文件失败:', _error);
  }
};

watch(
  () => [props.src, props.color],
  ([newSrc, newColor]) => {
    // #ifdef MP-WEIXIN | APP-PLUS
    fetchSvgFile(newSrc, newColor);
    // #endif
    // #ifdef H5
    svgData.value = newSrc;
    // #endif
  },
  { immediate: true },
);
</script>

<template>
  <image
    :src="svgData"
    :style="{ width, height }"
    mode="aspectFit"
    @click="$emit('click')"
  />
</template>

<style scoped>
/* 添加你的样式 */
</style>
